home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
gepackte_disketten
/
1993
/
09_93_2.dms
/
09_93_2.adf
/
Multitasking
/
Task-Erweitert.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-19
|
12KB
|
426 lines
; /*
sc ignore=104,73 streq shortint strmerge link map task
quit
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <devices/timer.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <intuition/gadgetclass.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/gadtools.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/timer.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <clib/macros.h>
#define STACKSIZE (4*1024)
#define TASKPRI 0
#define TASKNAME "Sample_Task"
#define SIG_SHOWMSG 0
#define SIG_EXIT 1
#define SIG_REPLY 2
#define SIG_MAX 3
#define GAD_REPLY 0
#define GAD_MODE 1
#define GAD_MAX 2
struct MemTag {
struct MemList mt_ML;
struct MemEntry mt_ME;
};
#define TFLGF_TIMERSET 0x0001
#define TFLGF_WATCH 0x0002
#define TFLGF_BUSYWAIT 0x0004
struct TaskTag {
struct Task tt_Task;
ULONG tt_flags;
UBYTE volatile tt_SigBit[SIG_MAX];
struct Task* volatile tt_SigTask[SIG_MAX];
UBYTE* volatile tt_message;
UWORD volatile tt_msglen;
ULONG volatile tt_lcount;
struct MsgPort *tt_timerport;
struct timerequest *tt_timerequest,tt_cyclic;
struct Library *tt_timerbase;
struct timeval volatile tt_tv0,tt_tvTskEntry,tt_tvUsed,tt_tvExpd;
int volatile tt_cpu;
};
#define TSK_SHOWMSG(t) ((t)->tt_SigTask[SIG_SHOWMSG])
#define TSK_EXIT(t) ((t)->tt_SigTask[SIG_EXIT])
#define TSK_REPLY(t) ((t)->tt_SigTask[SIG_REPLY])
#define BIT_SHOWMSG(t) ((t)->tt_SigBit[SIG_SHOWMSG])
#define BIT_EXIT(t) ((t)->tt_SigBit[SIG_EXIT])
#define BIT_REPLY(t) ((t)->tt_SigBit[SIG_REPLY])
#define MSK_SHOWMSG(t) (1L << BIT_SHOWMSG(t))
#define MSK_EXIT(t) (1L << BIT_EXIT(t))
#define MSK_REPLY(t) (1L << BIT_REPLY(t))
#define TimerBase (t->tt_timerbase)
extern struct IntuitionBase *IntuitionBase;
extern struct Library *GadToolsBase;
extern struct GfxBase *GfxBase;
void __interrupt Launch(void) {
struct TaskTag *t = (struct TaskTag*)FindTask(NULL);
if(t->tt_flags & TFLGF_TIMERSET) {
t->tt_flags |= TFLGF_WATCH;
t->tt_lcount++;
GetSysTime(&t->tt_tvTskEntry);
}
}
#define MILLION 1000000L
void __interrupt Switch(void) {
struct TaskTag *t = (struct TaskTag*)FindTask(NULL);
if(t->tt_flags & TFLGF_WATCH) {
t->tt_flags &= ~TFLGF_WATCH;
GetSysTime(&t->tt_timerequest->tr_time);
t->tt_tvExpd = t->tt_timerequest->tr_time;
SubTime(&t->tt_tvExpd,&t->tt_tv0);
SubTime(&t->tt_timerequest->tr_time,&t->tt_tvTskEntry);
AddTime(&t->tt_tvUsed,&t->tt_timerequest->tr_time);
t->tt_cpu = 100L * (t->tt_tvUsed.tv_secs * MILLION
+ t->tt_tvUsed.tv_micro) / (t->tt_tvExpd.tv_secs
* MILLION + t->tt_tvExpd.tv_micro);
}
}
void __interrupt DisposeWindow(struct Window *w) {
struct Gadget *g = w->FirstGadget;
CloseWindow(w);
FreeGadgets(g);
}
#define G_WIDTH 100
#define G_HEIGHT 30
#define B_TOP(w) ((w)->BorderTop + 5 + G_HEIGHT)
#define B_LEFT(w) ((w)->BorderLeft + 3)
#define B_HEIGHT(w) ((w)->Height - (w)->BorderTop -\
(w)->BorderBottom - G_HEIGHT - 7)
#define B_WIDTH(w) ((w)->Width - (w)->BorderLeft -\
(w)->BorderRight - 6)
struct Gadget *wg[GAD_MAX];
struct Window* __interrupt InitWindow(void) {
APTR vi; struct NewGadget ng;
struct Screen *ps; struct Window *w;
struct Gadget *gl,*gad = NULL;
if(ps = LockPubScreen(NULL)) {
if(vi = GetVisualInfoA(ps,NULL)) {
if(gad = CreateContext(&gl)) {
static UBYTE *cycle_labels[] = {
"Signal Wait","Busy Wait",NULL
};
ng.ng_LeftEdge = ps->WBorLeft + 3;
ng.ng_TopEdge = ps->BarHeight + 4;
ng.ng_Width = G_WIDTH;
ng.ng_Height = G_HEIGHT;
ng.ng_VisualInfo = vi;
ng.ng_GadgetText = "Reply";
ng.ng_TextAttr = ps->Font;
ng.ng_Flags = PLACETEXT_IN;
ng.ng_GadgetID = 0;
ng.ng_UserData = NULL;
wg[GAD_REPLY] = gad = CreateGadget(BUTTON_KIND,
gad,&ng,GA_Disabled,1L,TAG_DONE);
ng.ng_LeftEdge = gad->LeftEdge + gad->Width + 1;
ng.ng_Width = G_WIDTH * 2 + 1;
ng.ng_GadgetText = NULL;
ng.ng_GadgetID = 1;
wg[GAD_MODE] = gad = CreateGadget(CYCLE_KIND,gad,&ng,
GTCY_Labels,cycle_labels,
GTCY_Active,0L,TAG_DONE);
if(w = OpenWindowTags(NULL,
WA_Flags,(ULONG)WFLG_DEPTHGADGET|WFLG_DRAGBAR,
WA_IDCMP,(ULONG)IDCMP_GADGETUP,
WA_InnerHeight,(ULONG)G_HEIGHT + 80L,
WA_InnerWidth,(ULONG)G_WIDTH * 3 + 8,
WA_Gadgets,gl,
WA_Title,TASKNAME,
WA_PubScreen,ps,
TAG_DONE)) {
GT_RefreshWindow(w,NULL);
SetAPen(w->RPort,1);
SetBPen(w->RPort,0);
SetDrMd(w->RPort,JAM2);
DrawBevelBox(w->RPort,B_LEFT(w),
B_TOP(w),B_WIDTH(w),B_HEIGHT(w),
GT_VisualInfo,vi,GTBB_Recessed,1L,TAG_DONE);
}
else FreeGadgets(gl);
}
FreeVisualInfo(vi);
}
UnlockPubScreen(NULL,ps);
}
return(w);
}
void __interrupt print(struct Window *w,UBYTE *text,int top,int len) {
SetAPen(w->RPort,0);
RectFill(w->RPort,B_LEFT(w) + 2,top -
w->RPort->Font->tf_Baseline,B_WIDTH(w) + 4,
top + w->RPort->Font->tf_YSize - w->RPort->Font->tf_Baseline);
Move(w->RPort,B_LEFT(w) + (B_WIDTH(w) - TextLength
(w->RPort,text,len)) / 2,top);
SetAPen(w->RPort,1);
Text(w->RPort,text,len);
}
void __interrupt ShowCPU(struct Window *w,struct TaskTag *t) {
UBYTE cpu_string[32];
sprintf(cpu_string,"Sw/s=%2ld, CPU (%ld/%ld) %2d%%",
t->tt_lcount / MAX(t->tt_tvExpd.tv_secs,1),
t->tt_tvUsed.tv_secs,t->tt_tvExpd.tv_secs,t->tt_cpu);
print(w,cpu_string,B_HEIGHT(w) / 2 -
w->RPort->Font->tf_Baseline + B_TOP(w),strlen(cpu_string));
}
#define AMIGAOS_V_37 37
void __saveds __interrupt SampleTask(void) {
struct TaskTag *t;
struct Window *w;
t = (struct TaskTag*)FindTask(NULL);
if(GfxBase = (struct GfxBase*)
OpenLibrary("graphics.library",AMIGAOS_V_37)) {
if(IntuitionBase = (struct IntuitionBase*)
OpenLibrary("intuition.library",AMIGAOS_V_37)) {
if(GadToolsBase = OpenLibrary("gadtools.library",AMIGAOS_V_37)) {
if(w = InitWindow()) {
if(t->tt_timerport = CreateMsgPort()) {
if(t->tt_timerequest = (struct timerequest*)
CreateIORequest(t->tt_timerport,sizeof(struct timerequest))) {
if(OpenDevice(TIMERNAME,UNIT_VBLANK,
t->tt_timerequest,0L) == 0) {
t->tt_cyclic = *t->tt_timerequest;
t->tt_timerbase = (struct Library*)
t->tt_timerequest->tr_node.io_Device;
GetSysTime(&t->tt_tv0);
t->tt_flags |= TFLGF_TIMERSET;
t->tt_cyclic.tr_node.io_Command = TR_ADDREQUEST;
t->tt_cyclic.tr_time.tv_secs = 0L;
t->tt_cyclic.tr_time.tv_micro = 400000L;
SendIO(&t->tt_cyclic.tr_node);
if((BIT_SHOWMSG(t) = AllocSignal(-1L)) != -1) {
TSK_SHOWMSG(t) = FindTask(NULL);
if((BIT_EXIT(t) = AllocSignal(-1L)) != -1) {
TSK_EXIT(t) = FindTask(NULL);
Signal(TSK_REPLY(t),MSK_REPLY(t));
while(1) {
ULONG sigset;
if(t->tt_flags & TFLGF_BUSYWAIT) {
sigset = SetSignal(0L,MSK_EXIT(t)
| MSK_SHOWMSG(t)
| 1L << t->tt_timerport->mp_SigBit
| 1L << w->UserPort->mp_SigBit);
}
else {
sigset = Wait(MSK_EXIT(t)
| MSK_SHOWMSG(t)
| 1L << t->tt_timerport->mp_SigBit
| 1L << w->UserPort->mp_SigBit);
}
if(sigset & 1L << t->tt_timerport->mp_SigBit) {
t->tt_cyclic.tr_node.io_Command = TR_ADDREQUEST;
t->tt_cyclic.tr_time.tv_secs = 0L;
t->tt_cyclic.tr_time.tv_micro = 400000L;
SendIO(&t->tt_cyclic.tr_node);
ShowCPU(w,t);
}
if(sigset & MSK_EXIT(t)) {
break;
}
if(sigset & MSK_SHOWMSG(t)) {
GT_SetGadgetAttrs(wg[GAD_REPLY],w,NULL,
GA_Disabled,0L,TAG_DONE);
RefreshGList(wg[0],w,NULL,1);
print(w,t->tt_message,
B_TOP(w) + B_HEIGHT(w) / 2 +
w->RPort->Font->tf_Baseline,t->tt_msglen);
}
if(sigset & 1L << w->UserPort->mp_SigBit) {
struct IntuiMessage *imsg;
while(imsg = GT_GetIMsg(w->UserPort)) {
ULONG im_code,im_class;
APTR im_address;
im_class = imsg->Class;
im_code = imsg->Code;
im_address = imsg->IAddress;
GT_ReplyIMsg(imsg);
switch(im_class) {
case IDCMP_GADGETUP:
switch(((struct Gadget*)
im_address)->GadgetID) {
case GAD_REPLY:
GT_SetGadgetAttrs(wg[GAD_REPLY],
w,NULL,GA_Disabled,1L,TAG_DONE);
RefreshGList(wg[0],w,NULL,1);
Signal(TSK_REPLY(t),MSK_REPLY(t));
break;
case GAD_MODE:
switch(im_code) {
case 0:
t->tt_flags &= ~TFLGF_BUSYWAIT;
break;
case 1:
t->tt_flags |= TFLGF_BUSYWAIT;
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
}
}
}
}
AbortIO(&t->tt_cyclic.tr_node);
WaitIO(&t->tt_cyclic.tr_node);
TSK_EXIT(t) = NULL;
FreeSignal(BIT_EXIT(t));
}
TSK_SHOWMSG(t) = NULL;
FreeSignal(BIT_SHOWMSG(t));
}
t->tt_flags &= ~(TFLGF_TIMERSET|TFLGF_WATCH);
CloseDevice(t->tt_timerequest);
}
DeleteIORequest(t->tt_timerequest);
}
DeleteMsgPort(t->tt_timerport);
}
DisposeWindow(w);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary(&IntuitionBase->LibNode);
}
CloseLibrary(&GfxBase->LibNode);
}
Forbid();
Signal(TSK_REPLY(t),MSK_REPLY(t));
Wait(0L); /* Wait forever... */
}
void main(void) {
struct TaskTag *ptt; struct MemList *pml;
struct MemTag aml; UBYTE SigBit; APTR stk;
aml.mt_ML.ml_Node.ln_Type = NT_MEMORY;
aml.mt_ML.ml_Node.ln_Pri = 0;
aml.mt_ML.ml_Node.ln_Name = TASKNAME;
aml.mt_ML.ml_NumEntries = 2;
aml.mt_ML.ml_ME[0].me_Un.meu_Reqs = MEMF_PUBLIC|MEMF_CLEAR;
aml.mt_ML.ml_ME[0].me_Length = sizeof(struct TaskTag);
aml.mt_ML.ml_ME[1].me_Un.meu_Reqs = MEMF_CLEAR;
aml.mt_ML.ml_ME[1].me_Length = STACKSIZE;
pml = AllocEntry(&aml.mt_ML);
if(!((ULONG)pml & (1L << 31))) {
ptt = (struct TaskTag*) pml->ml_ME[0].me_Un.meu_Addr;
stk = (APTR) pml->ml_ME[1].me_Un.meu_Addr;;
ptt->tt_Task.tc_Node.ln_Pri = TASKPRI;
ptt->tt_Task.tc_Node.ln_Type = NT_TASK;
ptt->tt_Task.tc_Node.ln_Name = TASKNAME;
ptt->tt_Task.tc_SPLower = stk;
ptt->tt_Task.tc_SPReg =
ptt->tt_Task.tc_SPUpper = (APTR)((ULONG)stk + STACKSIZE);
NewList(&ptt->tt_Task.tc_MemEntry);
AddHead(&ptt->tt_Task.tc_MemEntry,&pml->ml_Node);
if((SigBit = AllocSignal(-1L)) != -1) {
BIT_REPLY(ptt) = SigBit;
TSK_REPLY(ptt) = FindTask(NULL);
AddTask(&ptt->tt_Task,(APTR)SampleTask,0L);
Disable();
ptt->tt_Task.tc_Launch = Launch;
ptt->tt_Task.tc_Switch = Switch;
ptt->tt_Task.tc_Flags |= (TF_LAUNCH|TF_SWITCH);
Enable();
Wait(MSK_REPLY(ptt));
while(1) {
int len;
UBYTE msg_buf[128];
Write(Output(),"Parent: ",8);
len = Read(Input(),msg_buf,128);
if(*msg_buf == '\n') break;
ptt->tt_message = msg_buf;
ptt->tt_msglen = len - 1;
Signal(TSK_SHOWMSG(ptt),MSK_SHOWMSG(ptt));
Wait(MSK_REPLY(ptt));
}
Signal(TSK_EXIT(ptt),MSK_EXIT(ptt));
Wait(MSK_REPLY(ptt));
RemTask(&ptt->tt_Task);
FreeSignal(SigBit);
}
}
exit(0);
}